C++ High Performance by Bjorn Andrist

C++ High Performance by Bjorn Andrist

Author:Bjorn Andrist
Language: eng
Format: epub, mobi
Publisher: Packt
Published: 2018-01-31T08:35:53+00:00


The new and delete operators

The function operator new is responsible for allocating memory when a new expression is invoked. The new operator can either be a globally defined function or a static member function of a class. It is possible to overload the global operators, new and delete. Later on in this chapter, we will see that this can be useful when analyzing memory usage. Here is how to do it:

auto operator new(size_t size) -> void* { void* p = std::malloc(size); std::cout << "allocated " << size << " byte(s)" << '\n'; return p; } auto operator delete(void* p) noexcept -> void { std::cout << "deleted memory\n"; return std::free(p); }

We can verify that our overloaded operators are actually being used when creating and deleting a char object:

auto* p = new char{'a'}; // Outputs "allocated 1 byte(s)" delete p; // Outputs "deleted memory"

When creating and deleting an array of objects using the new[] and delete[] expressions, there is another pair of operators that are being used, namely operator new[] and operator delete[]. We can overload these operators in the same way:

auto operator new[](size_t size) -> void* { void* p = std::malloc(size); std::cout << "allocated " << size << " byte(s) with new[]" << '\n'; return p; } auto operator delete[](void* p) noexcept -> void { std::cout << "deleted memory with delete[]\n"; return std::free(p); }

Keep in mind that if you overload operator new, you should also overload operator delete. Functions for allocating and deallocating memory come in pairs. Memory should be deallocated by the allocator that the memory was allocated by. For example, memory allocated with std::malloc() should always be freed using std::free(). Memory allocated with operator new[] should be deallocated using operator delete[].

It is also possible to override a class-specific operator new and operator delete. This is probably more useful than overloading the global operators, since it is more likely that we need a custom dynamic memory allocator for a specific class. Here, we are overloading operator new and operator delete for the Document class:

class Document { // ... public: auto operator new(size_t size) -> void* { return ::operator new(size); } auto operator delete(void* p) -> void { ::operator delete(p); } };

The class-specific version of new will be used when we create new dynamically allocated Document objects:

auto* p = new Document{}; // Uses class-specific operator new delete p;

If we instead want to use global new and delete, it is still possible by using the global scope (::):

auto* p = ::new Document{}; // Uses global operator new ::delete p;

We will discuss memory allocators later in this chapter and we will then see the overloaded new and delete operators in use. To summarize what we have seen so far, a new expression involves two things: allocation and construction. operator new allocates memory and you can overload it globally or per class to customize dynamic memory management. Placement new can be used to construct an object in an already allocated memory area.



Download



Copyright Disclaimer:
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.